package cz.cvut.manatee.client.login;

import java.util.LinkedList;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

import cz.cvut.manatee.client.Locator;
import cz.cvut.manatee.client.TrimTextBox;
import cz.cvut.manatee.shared.login.User;
import cz.cvut.manatee.shared.login.UserInfo;
import cz.cvut.manatee.shared.login.UserNotLogged;

public class LoginWidget extends Composite {
	private final String KEYWORD_HEADER =     "Přihlášení do aplikace";
	private final String KEYWORD_LOGIN        = "login:";
	private final String KEYWORD_PASS         = "password:";
	private final String KEYWORD_SEND         = "Log in";
	private final String KEYWORD_VERIFICATION = "Verification in progress...";
	private final String KEYWORD_NOTLOGGED    = "Bad username or password";
	
	private LinkedList<LoginHandler> loginHandlers; 
	
	private TrimTextBox login;
	private PasswordTextBox password;
	private Button send;
	private Label error;
	private Label verification;
	private VerticalPanel panel;
	
	public LoginWidget() {
		LoginResources.INSTANCE.css().ensureInjected();
		
		loginHandlers = new LinkedList<LoginHandler>();
		
		login        = new TrimTextBox();
		password     = new PasswordTextBox();
		send         = new Button(KEYWORD_SEND);
		error        = new Label(KEYWORD_NOTLOGGED);
		verification = new Label(KEYWORD_VERIFICATION);
		panel        = new VerticalPanel();
		
		error.setVisible(false);
		verification.setVisible(false);
		
		Grid tab     = new Grid(3, 2);
		
		tab.setWidget(0, 0, new Label(KEYWORD_LOGIN));
		tab.setWidget(0, 1, login);
		tab.setWidget(1, 0, new Label(KEYWORD_PASS));
		tab.setWidget(1, 1, password);
		tab.setWidget(2, 1, send);
		
		panel.add(new HTML("<h1>" + KEYWORD_HEADER + "</h1>"));
		panel.add(verification);
		panel.add(error);
		panel.add(tab);
		
		this.initWidget(panel);
		
		
		
		
		this.send.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LoginWidget.this.login();
			}
		});
		
	}
	
	/**
	 * Vraci udalost, pokud uzivatel je overen na serveru
	 */
	public void addLoginHandler(LoginHandler handler) {
		this.loginHandlers.add(handler);
	}
	
	public String getLogin() {
		return this.login.getValue();
	}
	
	public String getPassword() {
		return this.password.getValue();
	}
	
	public void setLogin(String login) {
		this.login.setValue(login, true);
	}
	
	public void setPassword(String passwors) {
		this.password.setValue(passwors, true);
	}
	
	public void login() {
		this.clearError();
		this.setVerification(true);
		
		Locator.getInstance().login(login.getValue(), password.getValue(), new AsyncCallback<User>() {
			public void onSuccess(User user){
				LoginWidget.this.setVerification(false);
				if (user instanceof UserInfo) {
					LoginWidget.this.fireLoginEvent(((UserInfo) user).getLogin(), ((UserInfo) user).getName());
				} else if ( user instanceof UserNotLogged) {
					LoginWidget.this.setError(KEYWORD_NOTLOGGED);
				} else {
					LoginWidget.this.setError("Unknown error");
				}
			}
			public void onFailure(Throwable t){
				LoginWidget.this.setVerification(false);
				LoginWidget.this.setError(t.getMessage());
			}
		});
	}
	
	private void fireLoginEvent(String login, String name) {
		for (LoginHandler hander : loginHandlers) {
			hander.onLogin(new LoginEvent(login, name));
		}
	}
	
	private void clearError() {
		error.setVisible(false);
		error.removeStyleName(LoginResources.INSTANCE.css().loginError());
	}
	
	private void setError(String reason) {
		error.setText(reason);
		error.setVisible(true);
		error.addStyleName(LoginResources.INSTANCE.css().loginError());
	}
	
	private void setVerification(boolean progress) {
		if (progress) {
			verification.setVisible(true);
			verification.setStyleName(LoginResources.INSTANCE.css().verification());
		} else {
			verification.setVisible(false);
			verification.removeStyleName(LoginResources.INSTANCE.css().verification());
		}
	}
}
